/*
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 * 
 * The Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
 *
 * The Initial Developer of the Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
 * Portions created by Mark A. Kobold are Copyright (C) 2000-2007. All Rights Reserved.
 *
 * Contributor(s): 
 *  Mark A. Kobold [mkobold <at> isqlviewer <dot> com].
 *  
 * If you didn't download this code from the following link, you should check
 * if you aren't using an obsolete version: http://www.isqlviewer.com
 */
package org.isqlviewer.ui.dnd;

import java.awt.Component;
import java.awt.Cursor;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import org.isqlviewer.model.JdbcSchemaTreeModel;
import org.isqlviewer.model.SchemaNode;
import org.isqlviewer.model.SchemaNodeType;
import org.isqlviewer.sql.QueryMetadata;
import org.isqlviewer.sql.ResultSetRenderer;
import org.isqlviewer.util.LoggableObject;

public class SchemaNodeRenderer extends LoggableObject implements Runnable {

    private Component component = null;
    private SchemaNode schemaNode = null;
    private JdbcSchemaTreeModel treeModel = null;

    private ResultSetRenderer nodeRenderer = null;

    public SchemaNodeRenderer(ResultSetRenderer nodeRenderer, JdbcSchemaTreeModel treeModel, Component component,
            SchemaNode schemaNode) {

        this.nodeRenderer = nodeRenderer;
        this.treeModel = treeModel;
        this.component = component;
        this.schemaNode = schemaNode;
    }

    public void run() {

        renderSchemaPath(component, schemaNode);
    }

    private void renderSchemaPath(Component owner, SchemaNode node) {

        boolean cursorSet = false;
        if (owner != null) {
            try {
                owner.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                cursorSet = true;
            } catch (Exception ignored) {
            }
        }

        try {

            DatabaseMetaData metadata = treeModel.getMetaData();
            String catalog = treeModel.getCurrentCatlog();
            String schema = treeModel.getCurrentSchema();

            SchemaNode parent = (SchemaNode) node.getParent();
            String selection = node.getUserObject();
            SchemaNodeType type = node.getNodeType();

            switch (type) {
                case DATA_TYPE_SET :
                    modelResultSet(metadata.getTypeInfo());
                    break;
                case TABLE_TYPE :
                    modelResultSet(metadata.getTables(catalog, schema, null, null));
                    break;
                case UDT_SET :
                    modelResultSet(metadata.getUDTs(catalog, schema, null, null));
                    break;
                case UDT_SET_DISTINCT :
                    modelResultSet(metadata.getUDTs(catalog, schema, null, new int[]{Types.DISTINCT}));
                    break;
                case UDT_SET_STRUCT :
                    modelResultSet(metadata.getUDTs(catalog, schema, null, new int[]{Types.STRUCT}));
                    break;
                case UDT_SET_JAVA_OBJECT :
                    modelResultSet(metadata.getUDTs(catalog, schema, null, new int[]{Types.JAVA_OBJECT}));
                    break;
                case UDT :
                    switch (parent.getNodeType()) {
                        case UDT_SET_DISTINCT :
                            modelResultSet(metadata.getUDTs(catalog, schema, selection, new int[]{Types.DISTINCT}));
                            break;
                        case UDT_SET_STRUCT :
                            modelResultSet(metadata.getUDTs(catalog, schema, selection, new int[]{Types.STRUCT}));
                            break;
                        case UDT_SET_JAVA_OBJECT :
                            modelResultSet(metadata.getUDTs(catalog, schema, selection, new int[]{Types.JAVA_OBJECT}));
                            break;
                        default :
                            break;
                    }
                    break;
                case PROCEDURE_SET :
                    modelResultSet(metadata.getProcedures(catalog, schema, null));
                    break;
                case PROCEDURE :
                    modelResultSet(metadata.getProcedures(catalog, schema, selection));
                    break;
                case COLUMN_SET :
                    modelResultSet(metadata.getColumns(catalog, schema, parent.getUserObject(), null));
                    break;
                case COLUMN :
                    String table = ((SchemaNode) parent.getParent()).getUserObject();
                    modelResultSet(metadata.getColumns(catalog, schema, table, selection));
                    break;
                case INDEX :
                    modelResultSet(metadata.getIndexInfo(catalog, schema, parent.getUserObject(), false, false));
                    break;
                case PRIMARY_KEYS :
                    modelResultSet(metadata.getPrimaryKeys(catalog, schema, parent.getUserObject()));
                    break;
                case EXPORTED_KEYS :
                    modelResultSet(metadata.getExportedKeys(catalog, schema, parent.getUserObject()));
                    break;
                case IMPORTED_KEYS :
                    modelResultSet(metadata.getImportedKeys(catalog, schema, parent.getUserObject()));
                    break;
                case TABLE_PRIVILIGES :
                    modelResultSet(metadata.getTablePrivileges(catalog, schema, parent.getUserObject()));
                    break;
                case TABLE :
                    modelResultSet(metadata.getTables(catalog, schema, selection, new String[]{parent.getUserObject()}));
                    break;
                case COLUMN_PRIVILIGES :
                    modelResultSet(metadata.getColumnPrivileges(catalog, schema, parent.getUserObject(), null));
                    break;
                case VERSION_COLUMNS :
                    modelResultSet(metadata.getVersionColumns(catalog, schema, parent.getUserObject()));
                    break;
                default :
                    org.isqlviewer.swing.SwingUtilities.beep();
                    break;
            }
        } catch (SQLException error) {
            error(node.getNodeType(), error);
        } finally {
            if (cursorSet && owner != null) {
                owner.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
            }
        }
    }

    private void modelResultSet(ResultSet set) throws SQLException {

        try {
            nodeRenderer.initialize();
            if (set != null) {
                nodeRenderer.statementInitialized("", set.getStatement());
                nodeRenderer.processResultSet("", set, "", 0);

                nodeRenderer.recieveResultsetWarnings(set, set.getWarnings());
            }
        } finally {
            nodeRenderer.finalizeStatement("", new QueryMetadata());
            try {
                if (set != null) {
                    set.close();
                }
            } catch (Throwable t) {
            }
        }
    }
}